import os
import uuid
import pyttsx3
from config.pyttsx3_config import settings
from exception.custom_exception import CustomErrorThrowException
from dao.pyttsx3_dao import AudioDAO
from entity.schema.pyttsx3_schema import TTSRequest, TTSResponse
from models.pyttsx3_model  import AudioFile
from utils.logger import logger


class TTSService:
    def __init__(self):
        self.engine = self._init_engine()
        logger.info("TTS服务初始化完成")

    def _init_engine(self):
        """初始化语音引擎"""
        try:
            engine = pyttsx3.init()
            return engine
        except Exception as e:
            logger.error(f"语音引擎初始化失败: {str(e)}")
            # 补充 status_code 和 detail 参数
            raise CustomErrorThrowException(status_code=500, detail="语音引擎初始化失败")

    def _select_voice(self, engine, voice_preference: str):
        """选择语音"""

        def find_voice(keywords):
            for voice in engine.getProperty('voices'):
                voice_info = f"{voice.id.lower()} {voice.name.lower()}"
                if all(keyword in voice_info for keyword in keywords):
                    engine.setProperty('voice', voice.id)
                    return voice.id
            return None

        if voice_preference != "auto":
            voice_id = find_voice([voice_preference.lower()])
            if voice_id:
                return voice_id
            logger.warning(f"未找到指定语音: {voice_preference}, 使用默认语音")
        else:
            voice_id = find_voice(["chinese", "zh"])
            if voice_id:
                return voice_id
            logger.warning("未找到中文语音, 使用默认语音")
        return None

    def generate_speech(self, request: TTSRequest) -> AudioFile:
        """生成语音文件"""
        try:
            engine = self.engine

            # 设置语音
            voice_id = self._select_voice(engine, request.voice)

            # 设置语速和音量
            engine.setProperty('rate', max(50, min(300, request.speed)))
            engine.setProperty('volume', max(0.0, min(1.0, request.volume)))

            # 生成唯一文件名
            filename = f"tts_{uuid.uuid4().hex}.wav"

            # 保存为音频文件
            filepath = os.path.join(settings.AUDIO_CACHE_DIR, filename)
            engine.save_to_file(request.text, filepath)
            engine.runAndWait()

            # 创建音频文件记录
            return AudioDAO.create_audio_file(
                filename=filename,
                text=request.text,
                voice=voice_id or "default",
                speed=request.speed,
                volume=request.volume
            )
        except Exception as e:
            logger.error(f"语音生成失败: {str(e)}")
            raise CustomErrorThrowException(f"语音生成失败: {str(e)}")

    def clean_old_files(self) -> int:
        """清理旧文件"""
        return AudioDAO.clean_old_files()